package com.earthea.scaffold.common.entity;

import cn.hutool.http.HttpStatus;
import com.earthea.common.exception.IErrorCode;
import com.earthea.scaffold.common.enums.HttpCodeEnum;
import com.earthea.scaffold.common.exception.ServiceException;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import org.apache.commons.lang3.reflect.ConstructorUtils;

/**
 * 公共响应体
 */
@Data
public class BaseRsp implements IErrorCode {
    private int code;

    private String msg;

    /**
     * 成功返回结果
     */
    public static BaseRsp success() {
        return success(BaseRsp.class);
    }

    /**
     * 成功返回结果
     */
    public static <T extends BaseRsp> T success(Class<T> clz) {
        T response = build(clz);
        response.setCode(HttpCodeEnum.SUCCESS.getCode());
        response.setMsg(HttpCodeEnum.SUCCESS.getMsg());
        return response;
    }

    /**
     * 成功返回结果
     */
    public static BaseRsp success(String msg) {
        BaseRsp response = new BaseRsp();
        response.setCode(HttpCodeEnum.SUCCESS.getCode());
        response.setMsg(msg);
        return response;
    }

    /**
     * 失败返回结果
     *
     * @param errorCode 错误码
     */
    public static <T extends BaseRsp> T failed(IErrorCode errorCode, Class<T> clz) {
        T response = build(clz);
        response.setCode(errorCode.getCode());
        response.setMsg(errorCode.getMsg());
        return response;
    }

    /**
     * 失败返回结果
     *
     * @param code    错误码
     * @param message 错误信息
     */
    public static BaseRsp failed(int code, String message) {
        BaseRsp response = new BaseRsp();
        response.setCode(code);
        response.setMsg(message);
        return response;
    }

    /**
     * 失败返回结果
     *
     * @param message 提示信息
     */
    public static <T extends BaseRsp> T failed(String message, Class<T> clz) {
        T response = build(clz);
        response.setCode(HttpCodeEnum.FAIL.getCode());
        response.setMsg(message);
        return response;
    }

    /**
     * 失败返回结果
     */
    public static <T extends BaseRsp> T failed(Class<T> clz) {
        return failed(HttpCodeEnum.FAIL, clz);
    }

    /**
     * 失败返回结果
     */
    public static BaseRsp failed() {
        return failed(HttpCodeEnum.FAIL, BaseRsp.class);
    }

    /**
     * 失败返回结果
     */
    public static BaseRsp failed(String message) {
        return failed(message, BaseRsp.class);
    }

    private static <T extends BaseRsp> T build(Class<T> clz) {
        try {
            return ConstructorUtils.invokeConstructor(clz);
        } catch (Exception e) {
            throw new ServiceException(e);
        }
    }

    @JsonIgnore
    public boolean isFailed() {
        return !isSuccess();
    }

    @JsonIgnore
    public boolean isSuccess() {
        return HttpStatus.HTTP_OK == getCode();
    }

    @Override
    public int getCode() {
        return this.code;
    }

    @Override
    public String getMsg() {
        return this.msg;
    }
}
